package com.bestcem.xm.qdes.controller.v2;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.qdes.entity.QdesProject;
import com.bestcem.xm.qdes.entity.QdesQstruct;
import com.bestcem.xm.qdes.service.QdesProjectService;
import com.bestcem.xm.qdes.service.QdesQstructService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.bestcem.xm.qdes.util.QstructConstant.*;

@Slf4j
@Api(tags = "问卷编辑-V2")
@RestController
@RequiredArgsConstructor
@RequestMapping("/qdes/v2/projects")
public class ProjectV2Controller {

    private @NonNull QdesProjectService projectService;
    private @NonNull QdesQstructService qstructService;

    @ApiOperation(value = "获取题目")
    @GetMapping("/{pid:[a-fA-F0-9]{24}}/questions/")
    public XmResultJson<Object> getReleasedQuestionsV2(@PathVariable String pid) {
        log.info("getReleasedQuestionsV2 projectId:{}", pid);
        QdesProject project = projectService.getById(pid);
        if (Objects.isNull(project)) {
            return XmResultJson.fail(-1, String.format("project[id=%s] not found", pid));
        }
        if (Objects.isNull(project.getReleaseVer()) || project.getReleaseVer().equals(0)) {
            return XmResultJson.success(new JSONArray());
        }

        LambdaQueryWrapper<QdesQstruct> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(QdesQstruct::getProjectId, pid)
                .eq(QdesQstruct::getVersion, project.getReleaseVer())
                .last("limit 1");
        QdesQstruct struct = qstructService.getOne(queryWrapper);
        if (Objects.isNull(struct)) {
            return XmResultJson.fail(-1, String.format("qstruct[projectID=%s,version=%d] not found", pid, project.getReleaseVer()));
        }

        List<JSONObject> qs = new ArrayList<>();
        List<JSONObject> sub_qs = new ArrayList<>();
        List<JSONObject> questions = projectService.getReleasedQuestions(project, struct);
        questions.forEach(q -> {
            String qtype = q.getString("qtype");
            String custom_qtype = Optional.ofNullable(q.getString("custom_qtype")).orElse(qtype);
            String title = q.getString("title");
            Integer gid = q.getInteger("gid");
            JSONArray items = MULTI_Q.contains(qtype) ? Optional.ofNullable(q.getJSONArray("items")).orElse(new JSONArray()) : new JSONArray();
            JSONArray rows = MATRIX_Q.contains(qtype) ? Optional.ofNullable(q.getJSONArray("rows_items")).orElse(new JSONArray()) : new JSONArray();
            if ("city".equals(qtype)) {
                //int index = Optional.ofNullable(q.getIntValue("info_level")).orElse(4);
                //getIntValue 默认返回0
                int index = Integer.parseInt(q.getOrDefault("info_level", 4).toString());
                List<JSONObject> subList = CITY_JSON.subList(0, index);
                items = JSONArray.parseArray(JSONArray.toJSONString(subList));
            } else if ("cascader".equals(qtype)) {
                JSONArray finalItems = new JSONArray();
                AtomicInteger startindex = new AtomicInteger(1);
                Optional.ofNullable(q.getJSONArray("group_list"))
                        .ifPresent(ary -> ary.forEach(k4 -> {
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("seq", String.valueOf(startindex));
                            jsonObject.put("title", k4);
                            finalItems.add(jsonObject);
                            startindex.getAndIncrement();
                        }));
                items = finalItems;
            } else if ("evaluation".equals(qtype)) {
                Optional<Object> tag = Optional.ofNullable(q.getJSONObject("current_template"))
                        .map(ol -> ol.get("tagList"));
                if (tag.isPresent()) {
                    items = JSONArray.parseArray(JSONArray.toJSONString(EVALUATION_NEW));
                } else {
                    items = JSONArray.parseArray(JSONArray.toJSONString(EVALUATION_OLD));
                }
            }

            if ("nps".equals(custom_qtype)) {
                JSONArray items_tag = new JSONArray();
                items_tag.addAll(items);
                items_tag.forEach(it -> {
                    JSONObject ot = (JSONObject) it;
                    String pre = ot.getString("seq");
                    ot.put("title", "NPS客户类型");
                    ot.put("seq", pre.concat("_tag"));
                });
                items.addAll(items_tag);
            }

            String cid = Optional.ofNullable(q.getString("cid")).orElse("");
            if (!rows.isEmpty() && !items.isEmpty()) {
                if (rows.size() == items.size()) {
                    for (int i = 0; i < rows.size(); i++) {
                        JSONObject row = rows.getJSONObject(i);
                        JSONObject it = items.getJSONObject(i);
                        JSONObject k4 = new JSONObject();
                        k4.put("id", gid.toString().concat("_").concat(row.getString("seq")).concat("_").concat(it.getString("seq")));
                        k4.put("gid", gid);
                        k4.put("cid", cid);
                        k4.put("index", cid);
                        k4.put("title", title);
                        k4.put("qtype", qtype);
                        k4.put("custom_qtype", custom_qtype);
                        k4.put("rowTitle", row.getString("title"));
                        k4.put("itemTitle", it.getString("title"));
                        sub_qs.add(k4);
                    }
                }
            } else if (!rows.isEmpty()) {
                for (int i = 0; i < rows.size(); i++) {
                    JSONObject row = rows.getJSONObject(i);
                    JSONObject k5 = new JSONObject();
                    k5.put("id", gid.toString().concat("_").concat(row.getString("seq")));
                    k5.put("gid", gid);
                    k5.put("cid", cid);
                    k5.put("index", cid);
                    k5.put("title", title);
                    k5.put("qtype", qtype);
                    k5.put("custom_qtype", custom_qtype);
                    k5.put("rowTitle", row.getString("title"));
                    sub_qs.add(k5);
                }
            } else if (!items.isEmpty()) {
                for (int i = 0; i < items.size(); i++) {
                    JSONObject it = items.getJSONObject(i);
                    JSONObject k5 = new JSONObject();
                    k5.put("id", gid.toString().concat("_").concat(it.getString("seq")));
                    k5.put("gid", gid);
                    k5.put("cid", cid);
                    k5.put("index", cid);
                    k5.put("title", title);
                    k5.put("qtype", qtype);
                    k5.put("custom_qtype", custom_qtype);
                    k5.put("itemTitle", it.getString("title"));
                    sub_qs.add(k5);
                }
            } else {
                JSONObject k5 = new JSONObject();
                k5.put("id", gid.toString());
                k5.put("gid", gid);
                k5.put("cid", cid);
                k5.put("index", cid);
                k5.put("title", title);
                k5.put("qtype", qtype);
                k5.put("custom_qtype", custom_qtype);
                sub_qs.add(k5);
            }

            if ("nps".equals(custom_qtype)) {
                sub_qs.stream().filter(q1 -> q1.getString("id").endsWith("tag"))
                        .forEach(q2 -> q2.remove("itemTitle"));
            } else if (!items.isEmpty() && SCORE_Q.contains(qtype) && items.size() == 1) {
                sub_qs.forEach(q2 -> q2.remove("itemTitle"));
            }
            qs.addAll(sub_qs);
        });

        return XmResultJson.success(qs);
    }

    @ApiOperation(value = "获取问卷最大gid")
    @GetMapping("/{id:[a-fA-F0-9]{24}}/gids")
    public XmResultJson<Integer> getProjectMaxGid(@PathVariable String id) {
        return XmResultJson.success(projectService.getProjectMaxGid(id));
    }

    @ApiOperation(value = "更新问卷最大gid")
    @PutMapping("/{id:[a-fA-F0-9]{24}}/gids")
    public XmResultJson<?> setProjectMaxGid(@PathVariable String id, @RequestBody Map map) {
        Integer maxGid = (Integer) map.get("max_gid");
        if (Objects.isNull(maxGid)) {
            return XmResultJson.fail(4, "max_gid is required");
        }
        return projectService.setProjectMaxGid(id, maxGid);
    }

    @ApiOperation(value = "单题倒计时")
    @GetMapping("/{pid:[a-fA-F0-9]{24}}/timecost/")
    public XmResultJson<List<JSONObject>> getTimeCost(@PathVariable String pid) {
        return XmResultJson.success(projectService.getTimeCost(pid, null));
    }

    @ApiOperation(value = "单题倒计时-保存")
    @PostMapping("/{pid:[a-fA-F0-9]{24}}/timecost/")
    public XmResultJson<Map> postTimeCost(@PathVariable String pid, @RequestBody JSONObject params) {
        projectService.postTimeCost(pid, params);
        return XmResultJson.success(new HashMap<>());
    }
}
